package cn.com.miaoto.controller;

import cn.com.miaoto.base.common.ReturnMsg;
import cn.com.miaoto.model.LoginUser;
import cn.com.miaoto.model.Menu;
import cn.com.miaoto.model.Role;
import cn.com.miaoto.service.LoginUserService;
import cn.com.miaoto.service.MenuService;
import cn.com.miaoto.service.RoleService;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class LoginController {

	@Resource
	private RoleService roleService;
	
	@Resource
	private LoginUserService loginUserService;
	
	@Resource
	private MenuService menuService;

	@Resource
	private AuthenticationManager authenticationManager;

	/**
     * 用户登录请求
     * @param userId
     * @return
     */
    @ResponseBody
    @PostMapping("/login")
    public Map<String,Object> login(String userId, String password, String imageCode, HttpSession session){
    	Map<String,Object> map=new HashMap<String,Object>();
    	if(StringUtils.isEmpty(imageCode)){
    		map.put("success", false);
    		map.put("errorInfo", "请输入验证码！");
    		return map;
    	}
		// 验证验证码
		String sessionCode = session.getAttribute("checkcode").toString();
    	if(!sessionCode.equalsIgnoreCase(imageCode)){
    		map.put("success", false);
    		map.put("errorInfo", "验证码输入错误！");
    		return map;
    	}
		UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(userId, password);
		final Authentication authentication = authenticationManager.authenticate(upToken);
		SecurityContextHolder.getContext().setAuthentication(authentication);
		try{
			Example tuserExample=new Example(LoginUser.class);
			tuserExample.or().andEqualTo("userId",userId);
			LoginUser currentUser=loginUserService.selectByExample(tuserExample).get(0);
			session.setAttribute("currentUser", currentUser);
			List<Role> roleList=roleService.selectRolesByUserId(String.valueOf(currentUser.getId()));
			map.put("roleList", roleList);
			map.put("roleSize", roleList.size());
			map.put("success", true);
			return map;
		}catch(Exception e){
			e.printStackTrace();
			map.put("success", false);
			map.put("errorInfo", "用户名或者密码错误！");
			return map;
		}
    }

//	@GetMapping("logout")
//	public String logout(HttpServletRequest request, HttpServletResponse response) {
//		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//		if (auth != null) {
//			new SecurityContextLogoutHandler().logout(request, response, auth);
//		}
//		return "login";
//	}

	/**
	 * 保存角色信息
	 * @param roleId
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@PostMapping("/saveRole")
	public Map<String,Object> saveRole(Integer roleId,HttpSession session)throws Exception{
		Map<String,Object> map=new HashMap<String,Object>();
		Role currentRole=roleService.selectByKey(roleId);
		// 保存当前角色信息
		session.setAttribute("currentRole", currentRole);
		putTmenuOneClassListIntoSession(session);
		map.put("success", true);
		return map;
	}

	/**
	 * 加载权限菜单
	 * @param session
	 * @return
	 * @throws Exception
	 * 这里传入的parentId是1
	 */
	@ResponseBody
	@GetMapping("/loadMenuInfo")
	public String loadMenuInfo(HttpSession session, Integer parentId)throws Exception{
		putTmenuOneClassListIntoSession(session);
		Role currentRole=(Role) session.getAttribute("currentRole");
		//根据当前用户的角色id和父节点id查询所有菜单及子集json
		String json=getAllMenuByParentId(parentId,currentRole.getId()).toString();
		return json;
	}

	/**
	 * 获取根频道所有菜单信息
	 * @param parentId
	 * @param roleId
	 * @return
	 */
	private JsonObject getAllMenuByParentId(Integer parentId, Integer roleId){
		JsonObject resultObject=new JsonObject();
		JsonArray jsonArray=this.getMenuByParentId(parentId, roleId);//得到所有一级菜单
		for(int i=0;i<jsonArray.size();i++){
			JsonObject jsonObject=(JsonObject) jsonArray.get(i);
			//判断该节点下时候还有子节点
			Example example=new Example(Menu.class);
			example.or().andEqualTo("pId",jsonObject.get("id").getAsString());
			//if("true".equals(jsonObject.get("spread").getAsString())){
			if (menuService.selectCountByExample(example)==0) {
				continue;
			}else{
				//由于后台模板的规定，一级菜单以title最为json的key
				resultObject.add(jsonObject.get("title").getAsString(), getAllMenuJsonArrayByParentId(jsonObject.get("id").getAsInt(),roleId));
			}
		}
		return resultObject;
	}



	//获取根频道下子频道菜单列表集合
	private JsonArray getAllMenuJsonArrayByParentId(Integer parentId,Integer roleId){
		JsonArray jsonArray=this.getMenuByParentId(parentId, roleId);
		for(int i=0;i<jsonArray.size();i++){
			JsonObject jsonObject=(JsonObject) jsonArray.get(i);
			//判断该节点下是否还有子节点
			Example example=new Example(Menu.class);
			example.or().andEqualTo("pId",jsonObject.get("id").getAsString());
			//if("true".equals(jsonObject.get("spread").getAsString())){
			if (menuService.selectCountByExample(example)==0) {
				continue;
			}else{
				//二级或三级菜单
				jsonObject.add("children", getAllMenuJsonArrayByParentId(jsonObject.get("id").getAsInt(),roleId));
			}
		}
		return jsonArray;
	}

	/**
	 * 根据父节点和用户角色id查询菜单
	 * @param parentId
	 * @param roleId
	 * @return
	 */
	private JsonArray getMenuByParentId(Integer parentId,Integer roleId){
		HashMap<String,Object> paraMap=new HashMap<String,Object>();
		paraMap.put("pid",parentId);
		paraMap.put("roleId",roleId);
		List<Menu> menuList=menuService.selectByParentIdAndRoleId(paraMap);
		JsonArray jsonArray=new JsonArray();
		for(Menu menu:menuList){
			JsonObject jsonObject=new JsonObject();
			jsonObject.addProperty("id", menu.getId()); // 节点id
			jsonObject.addProperty("title", menu.getName()); // 节点名称
			jsonObject.addProperty("spread", false); // 不展开
			jsonObject.addProperty("icon", menu.getIcon());
			if(!StringUtils.isEmpty(menu.getUrl())){
				jsonObject.addProperty("href", menu.getUrl()); // 菜单请求地址
			}
			jsonArray.add(jsonObject);

		}
		return jsonArray;
	}

	public void putTmenuOneClassListIntoSession(HttpSession session){
		//用来在welcome.ftl中获取主菜单列表
		Example example=new Example(Menu.class);
		example.or().andEqualTo("pId",1);
		List<Menu> tmenuOneClassList=menuService.selectByExample(example);
		session.setAttribute("tmenuOneClassList", tmenuOneClassList);
	}
}
